package com.idea.relax.log.config;

import com.idea.relax.log.appender.file.LoggingFileAppender;
import com.idea.relax.log.appender.file.LoggingFileJsonAppender;
import com.idea.relax.log.appender.kafka.LoggingKafkaAppender;
import com.idea.relax.log.appender.logstash.LoggingLogStashAppender;
import com.idea.relax.log.props.RelaxLogProperties;
import com.idea.relax.log.support.ConditionalMultiple;
import com.idea.relax.log.support.ConditionalOnLoggingType;
import com.idea.relax.log.support.LoggingType;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.kafka.core.KafkaTemplate;

/**
 * @className: AppenderAutoConfiguration
 * @description: RelaxLog Appender的自动配置类
 * @author: salad
 * @date: 2023/1/23
 **/

@EnableConfigurationProperties({RelaxLogProperties.class})
public class AppenderAutoConfiguration {

    @Order
    @Configuration(
            proxyBeanMethods = false
    )
    @ConditionalOnLoggingType(LoggingType.LOGBACK)
    @ConditionalMultiple(
            classNames = {
                    "ch.qos.logback.core.rolling.RollingFileAppender"
            },
            attributes = {
                    RelaxLogProperties.PREFIX + RelaxLogProperties.ENABLED,
                    RelaxLogProperties.FileLog.PREFIX + ".enabled",
                    RelaxLogProperties.FileLog.PREFIX + ".use-json-format",
            }, havingValues = {"true","true","false"})
    public static class FileLogConfiguration {
        @Bean("loggingFileAppender")
        @ConditionalOnMissingBean(name = "loggingFileAppender")
        public LoggingFileAppender loggingFileAppender(Environment environment,
                                                       RelaxLogProperties properties) {
            return new LoggingFileAppender(environment, properties);
        }
    }

    @Order
    @Configuration(
            proxyBeanMethods = false
    )
    @ConditionalOnLoggingType(LoggingType.LOGBACK)
    @ConditionalMultiple(
            classNames = {
                    "net.logstash.logback.appender.LogstashTcpSocketAppender",
                    "ch.qos.logback.core.rolling.RollingFileAppender"
            },
            attributes = {
                    RelaxLogProperties.PREFIX + RelaxLogProperties.ENABLED,
                    RelaxLogProperties.FileLog.PREFIX + ".enabled",
                    RelaxLogProperties.FileLog.PREFIX + ".use-json-format",
            }, havingValues = {"true","true","true"})
    public static class FileJsonLogConfiguration {
        @Bean("loggingFileJsonAppender")
        @ConditionalOnMissingBean(name = "loggingFileJsonAppender")
        public LoggingFileJsonAppender loggingFileJsonAppender(Environment environment,
                                                               RelaxLogProperties properties) {
            return new LoggingFileJsonAppender(environment, properties);
        }
    }

    @Order
    @Configuration(
            proxyBeanMethods = false
    )
    @ConditionalOnLoggingType(LoggingType.LOGBACK)
    @ConditionalMultiple(
            classNames = {"net.logstash.logback.appender.LogstashTcpSocketAppender"},
            attributes = {
                    RelaxLogProperties.PREFIX + RelaxLogProperties.ENABLED,
                    RelaxLogProperties.LogstashLog.PREFIX + ".enabled"
            }, havingValues = {"true", "true"})
    public static class LogStashLogConfiguration {

        @Bean("loggingLogStashAppender")
        @ConditionalOnMissingBean(name = "loggingLogStashAppender")
        public LoggingLogStashAppender loggingLogStashAppender(RelaxLogProperties properties) {
            return new LoggingLogStashAppender(properties);
        }

    }

    @Order
    @Configuration(
            proxyBeanMethods = false
    )
    @ConditionalOnLoggingType(LoggingType.LOGBACK)
    @ConditionalMultiple(
            classNames = {"org.springframework.kafka.core.KafkaTemplate"},
            attributes = {
                    RelaxLogProperties.PREFIX + RelaxLogProperties.ENABLED,
                    RelaxLogProperties.KafkaLog.PREFIX + ".enabled"
            }, havingValues = {"true", "true"})
    public static class KafkaLogConfiguration {

        @Bean("loggingKafkaAppender")
        @ConditionalOnMissingBean(name = "loggingKafkaAppender")
        public LoggingKafkaAppender loggingKafkaAppender(RelaxLogProperties properties,
                                                         ObjectProvider<KafkaTemplate<String, String>> objectProvider) {
            return new LoggingKafkaAppender(properties, objectProvider.getIfAvailable());
        }

    }


}
